/* PR c/102989 */
/* { dg-do run { target bitint } } */
/* { dg-options "-std=c23 -pedantic-errors" } */
/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */

#if __BITINT_MAXWIDTH__ >= 256
__attribute__((noipa)) void
test256 (_BitInt(256) *p, _BitInt(256) *q, unsigned n)
{
  _BitInt(256) x = q[0], y;
  unsigned _BitInt(256) z;
  p[0] = x >= 0 ? x : -x;
  x = q[1];
  p[1] = (_BitInt(256)) (-(_BitInt(256)) (x < 0) | 1) * (unsigned _BitInt(256)) x;
  x = q[2];
  y = q[3];
  p[2] = x > y ? x : y;
  p[3] = x < y ? x : y;
  z = q[4];
  p[4] = (z << n) | (z >> (-n) % 256);
  z = q[5];
  p[5] = (z >> n) | (z << (-n) % 256);
  z = q[6];
  p[6] = (z << 42) | (z >> (256 - 42));
  p[7] = (z << 196) | (z >> (256 - 196));
}
#endif

#if __BITINT_MAXWIDTH__ >= 575
__attribute__((noipa)) void
test575 (_BitInt(575) *p, _BitInt(575) *q, unsigned n)
{
  _BitInt(575) x = q[0], y;

  p[0] = x >= 0 ? x : -x;
  x = q[1];
  p[1] = (_BitInt(575)) (-(_BitInt(575)) (x < 0) | 1) * (unsigned _BitInt(575)) x;
  x = q[2];
  y = q[3];
  p[2] = x > y ? x : y;
  p[3] = x < y ? x : y;
  x = q[4];
  p[4] = (x << n) | (x >> (-n) % 575);
  x = q[5];
  p[5] = (x >> n) | (x << (-n) % 575);
  x = q[6];
  p[6] = (x << 42) | (x >> (575 - 42));
  p[7] = (x << 196) | (x >> (575 - 196));
}
#endif

int
main ()
{
#if __BITINT_MAXWIDTH__ >= 256
  _BitInt(256) p256[16];
  static _BitInt(256) q256[14] = {
    45345032714412617256156490782169070529322290545773058110333871537162440472587wb,
    -57896044618658097711785492504343953926634992332820282019728792003956564819968wb,
    56362660930901219937245963089077503913881996661810533276822951833224961233515wb,
    51868771107222588126287278424861243128427600270521502351207927942060821222194wb,
    -19284414951568262238262918143892955489617856897512953183940840506431869697041wb,
    2658782266882101281962762454025964999131551132761759005892140732613414118676wb,
    54220248433725687265393292224175077483742748899396150017145360542924235344802wb,
    -37463226851796965187185951868838571299559805464590722337979740082646767802569wb,
    -40419708661355022203345898421408637080086749636846240100217688555626587286030wb,
    -55754487912560053024413264564540814098917966752804384445133242149913646068176wb,
    26265770627437470876117322526967897715823682246510518833106882615653395455635wb,
    -52596268389191266164863111650546248051760002564726896605115288580144402763386wb,
    -44308970341715903069333400701791033613751134794232782967956437254511180029758wb,
    4750616739884184263118039796682749720523215747547537773188931304361332774085wb
  };
  static const _BitInt(256) r256[16] = {
    45345032714412617256156490782169070529322290545773058110333871537162440472587wb,
    -57896044618658097711785492504343953926634992332820282019728792003956564819968wb,
    56362660930901219937245963089077503913881996661810533276822951833224961233515wb,
    51868771107222588126287278424861243128427600270521502351207927942060821222194wb,
    28504845637216227099157296646299447493773190228564580204434798695467761710135wb,
    13952419655888133019367679114949332038269119423004786217260238955159715384317wb,
    55062854366581286125448024237607745201868855087201663327097902939898842371913wb,
    -48537283185021244092191938290513862066611838578912383503471331209866218456054wb,
    37463226851796965187185951868838571299559805464590722337979740082646767802569wb,
    40419708661355022203345898421408637080086749636846240100217688555626587286030wb,
    26265770627437470876117322526967897715823682246510518833106882615653395455635wb,
    -55754487912560053024413264564540814098917966752804384445133242149913646068176wb,
    -52596268389191266164863111650546248051760002564726896605115288580144402763386wb,
    -44308970341715903069333400701791033613751134794232782967956437254511180029758wb,
    -18143335929783282380882063933743228881911720395868748284571317433159558897346wb,
    29051936395101664965352348496634886321943246606527498619351354372469657269685wb
  };
  test256 (p256, q256, 31);
  test256 (p256 + 8, q256 + 7, 0);
  for (int i = 0; i < 16; ++i)
    if (p256[i] != r256[i])
      __builtin_abort ();
#endif
#if __BITINT_MAXWIDTH__ >= 575
  _BitInt(575) p575[16];
  static _BitInt(575) q575[14] = {
    -22872451846054556417350916741013404184330732279497241442289048103235716890482482649099537178446621346041121532737887637378213104798444471078041166778940100084060290561371455wb,
    17785619680254441647827488871998638273432777299970128558821267200272839955229298488625220894043625699693270092672797162273950619203800446486815325568472958573446749051572825wb,
    -734234098097989409262727998397700256489421637915860389242752385873657556883074595636809785650192226409399868870242355685621686958186408269916495700324885703256092385869434wb,
    38120499666250922171546613830180673200675976218799529299148065967941552755802535392332731940070002883710338820964987361658591561975335652756278138538832118604974787875400446wb,
    5684104948137619484333794789281535519196217253613879268155482366016410402198153437845962821374710383639946025491278662358930601323825409782517946368713730166779501012971475wb,
    32087820847816972971171692099083158156912701591228441301893931157856913053317602595432786417564970426631926727346659054532034068327088444234192931989166459782227197939321057wb,
    -21721263360652995330393989849576970088245889949682845009460695472717466152081539971263312012527739590286540576183877575156900293418340395132947924863443109127173995560078279wb,
    -15480195498062309558312832142884391233286002177523144097946171600675924728664105138320506609593544010951582863517501340004263677508611453722210182190275179605668158636665993wb,
    55995880469793772523539449728006933885804379190436425191858349409824731357990351725719664053451797096177518772823017250471021319053248877819795135618917529149253258308759354wb,
    24370295507731130004798276928243731386820125439099070643489522771145691875100529624831680686321147169119505764999828531144118172785865370931653507615753544737698580795350286wb,
    -13016142173054302003336690685586422149429100823007010246177815738538602088089262263144796610097444570064192302085091825355979550567585055268099892750197109319237803857300389wb,
    -35368478429854967484145020710656986046297257815593959870285507974957270671233443946755652228033821286859588583452449353741836352125387357246827468277473775502648515381353900wb,
    58764573942155814375791739663233093461596472170763698081763161612851239717416911428930198048960628406552049393162750872881771056037803284665755551481777372772007145066447638wb,
    44433183924809544824417284909271563263644800797277575618994531425499154930034075648536496209651260196970467671003251328672885483954369513730487082628591112972000580073953662wb,
  };
  static const _BitInt(575) r575[16] = {
    22872451846054556417350916741013404184330732279497241442289048103235716890482482649099537178446621346041121532737887637378213104798444471078041166778940100084060290561371455wb,
    17785619680254441647827488871998638273432777299970128558821267200272839955229298488625220894043625699693270092672797162273950619203800446486815325568472958573446749051572825wb,
    38120499666250922171546613830180673200675976218799529299148065967941552755802535392332731940070002883710338820964987361658591561975335652756278138538832118604974787875400446wb,
    -734234098097989409262727998397700256489421637915860389242752385873657556883074595636809785650192226409399868870242355685621686958186408269916495700324885703256092385869434wb,
    21703548306654828422881171931811440617567232925929621047938944826274955122606664179955511692787137409674737460976041867927943552583691691300165016729177283086471793752300456wb,
    26132710036535820372804820434723627712036525396244440920377271153766059995978577234280974829431879549681083853195499953729715766325604759212344321343859158691727036603084808wb,
    -772498050957wb,
    -17640736973552882046941821064235973435654602283914963062775wb,
    15480195498062309558312832142884391233286002177523144097946171600675924728664105138320506609593544010951582863517501340004263677508611453722210182190275179605668158636665993wb,
    55995880469793772523539449728006933885804379190436425191858349409824731357990351725719664053451797096177518772823017250471021319053248877819795135618917529149253258308759354wb,
    24370295507731130004798276928243731386820125439099070643489522771145691875100529624831680686321147169119505764999828531144118172785865370931653507615753544737698580795350286wb,
    -13016142173054302003336690685586422149429100823007010246177815738538602088089262263144796610097444570064192302085091825355979550567585055268099892750197109319237803857300389wb,
    -35368478429854967484145020710656986046297257815593959870285507974957270671233443946755652228033821286859588583452449353741836352125387357246827468277473775502648515381353900wb,
    58764573942155814375791739663233093461596472170763698081763161612851239717416911428930198048960628406552049393162750872881771056037803284665755551481777372772007145066447638wb,
    -49246536424904916635319663180286717016047461257207957146338535716423124695209459892760482984419623560832895613229564098885770525356171820890930378678203734061651571774762747wb,
    -24090226615157470281984717279507286428793968193916029900229071481754838071202669524668562579828294907607719783763180294251525168293397875645175326412340936012077133238990588wb
  };
  test575 (p575, q575, 31);
  test575 (p575 + 8, q575 + 7, 0);
  for (int i = 0; i < 16; ++i)
    if (p575[i] != r575[i])
      __builtin_abort ();
#endif
}
